package com.modular.system.msg.opt;

import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import com.ToolOpt;
import com.c.opt.ComOpt;
import com.modular.system.msg.Msg;
import com.tool.ToolRedisson;
import ntd.util.config.common.enums.msg.EnumMsgHandle;
import ntd.util.config.common.enums.msg.EnumMsgState;
import ntd.util.config.common.exception.ComException;
import ntd.util.frame.msg.bo.MsgInBO;
import ntd.util.frame.msg.bo.MsgInfo;
import ntd.util.frame.msg.service.context.MsgContext;
import ntd.util.modular.function.util.UtilChannelBusiness;

import java.time.Duration;

/**
 * 消息处理操作
 */
public class OptMsg extends ComOpt<Msg> {

    public OptMsg() {
        super("message_msg");
    }

    /**
     * 消息发送成功
     * @param msgIn
     */
    public void success(Msg msgIn) {
        Msg msg = new Msg();
        msg.setId(Opt.ofBlankAble(msgIn.getId()).orElseThrow(() -> new ComException("消息发送成功-执行错误, 缺少唯一标识...")));
        msg.setState(EnumMsgState.SEND_SUCCESS);
        syncBean(msg);
    }

    /**
     * 消息发送失败
     * @param msgIn
     */
    public void error(Msg msgIn) {
        Msg msg = new Msg();
        msg.setId(Opt.ofBlankAble(msgIn.getId()).orElseThrow(() -> new ComException("消息发送成功-执行错误, 缺少唯一标识...")));
        msg.setState(EnumMsgState.SEND_ERROR);
        syncBean(msg);
    }

    /**
     * 发送消息
     * @param msgInBO
     * @return
     */
    public String putMsg(MsgInBO msgInBO) {
        // 消息唯一标识
        String encode = DigestUtil.sha256Hex(JSONUtil.toJsonStr(msgInBO));
        return ToolRedisson.me.get("com-msg-key-" + encode, () -> {
            // 保存返回消息id
            Msg msg = transform(msgInBO);
            msg.setId(syncBean(msg));
            sendMsg(msg);
            return msg.getId();
        }, Duration.ofSeconds(60 * 10));
    }

    public void sendMsg(Msg msg) {
        try {
            Opt.ofNullable(msg.getEnumMsgHandle()).ifPresent(enumMsgHandle -> {
                enumMsgHandle.getMsgHandle().handle(init(msg));
                // 更新消息状态
                success(msg);
            });
        } catch (Exception e) {
            StaticLog.error(e, "[消息][发送][{}]失败...", JSONUtil.toJsonStr(msg));
            // 更新消息状态
            error(msg);
        }
    }

    private MsgContext init(Msg msg) {
        return MsgContext.init(msg, Opt.ofNullable(UtilChannelBusiness.getById(msg.getChannelBusinessId()))
                .orElseThrow(() -> new ComException("找不到渠道商[{}]信息...", msg.getChannelBusinessId())));
    }

    private static Msg transform(MsgInBO msgInBO) {
        Msg msg = new Msg();

        if (StrUtil.isAllBlank(msgInBO.getReceiverIds(), msgInBO.getReceiverAlias(), msgInBO.getReceiverTags(), msgInBO.getReceiverPhones(), msgInBO.getReceiverEmails())) {
            throw new ComException("收件人不能为空");
        }
        msg.setReceiverJson(buildReceiver(msgInBO).toString());
        msg.setSender(Opt.ofBlankAble(msgInBO.getMsgSenderUserId()).orElse("-1"));
        msg.setDataJson(msgInBO.getDataJson());
        msg.setEnumMsgHandle(Opt.ofNullable(msgInBO.getEnumMsgHandle()).orElseThrow(() -> new ComException("消息发送类型不能为空")));
        msg.setChannelBusinessId(Opt.ofBlankAble(msgInBO.getChannelBusinessId()).orElseThrow(() -> new ComException("渠道商信息不能为空")));

        Opt.ofNullable(msgInBO.getMsgInfo()).ifPresent(msgInfo -> {
            msg.setTitle(msgInfo.getTitle());
            msg.setLink(msgInfo.getLink());
            msg.setContent(msgInfo.getContent());
        });

        return msg;
    }

    private static JSONObject buildReceiver(MsgInBO msgInBO) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.putOnce("ids", msgInBO.getReceiverIds());
        jsonObject.putOnce("alias", msgInBO.getReceiverAlias());
        jsonObject.putOnce("tags", msgInBO.getReceiverTags());
        jsonObject.putOnce("phones", msgInBO.getReceiverPhones());
        jsonObject.putOnce("emails", msgInBO.getReceiverEmails());
        return jsonObject;
    }

    public static void main(String[] args) {
        MsgInBO msgInBO = new MsgInBO();
        msgInBO.setChannelBusinessId("2c906edb7fd39df1017fd3cc9a54000b");
        msgInBO.setMsgSenderUserId("-1");
        msgInBO.setMsgInfo(MsgInfo.init("测试消息内容!"));
        msgInBO.setReceiverPhones("18837132130");
        msgInBO.setEnumMsgHandle(EnumMsgHandle.JPUSH_SMS);


        JSONObject templateParams = new JSONObject();
        templateParams.putOnce("site_name", "基站名称");
        templateParams.putOnce("warning_type", "告警类型");
        templateParams.putOnce("cause", "提示信息");

        JSONObject jsonParams = JSONUtil.createObj();
        jsonParams.putOnce("templateCode", "1");
//        jsonParams.putOnce("signId", "21295");
        jsonParams.putOnce("signId", "24858");
        jsonParams.putOnce("templateParams", templateParams);

        msgInBO.setDataJson(jsonParams.toString());

        StaticLog.info(ToolOpt.OPT_MSG.putMsg(msgInBO));
        StaticLog.info(ToolOpt.OPT_MSG.putMsg(msgInBO));
        StaticLog.info(ToolOpt.OPT_MSG.putMsg(msgInBO));
        StaticLog.info(ToolOpt.OPT_MSG.putMsg(msgInBO));
        StaticLog.info(ToolOpt.OPT_MSG.putMsg(msgInBO));
    }

}
